'''
# encoding=utf-8

'''
import warnings

warnings.filterwarnings('ignore')
#显示中文
from pylab import *  #显示中文

mpl.rcParams['font.sans-serif'] = ['SimHei']  #显示中文
#画图中显示负号
import matplotlib

matplotlib.rcParams['axes.unicode_minus'] = False

import os
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split,cross_val_score,GridSearchCV
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn import metrics
import matplotlib.pyplot as plt

# 现有文件名为aviation的航空客运信息数据集，共包括5000个样本，每个样本有55个属性，其中runoff_flag代表是否流失，要求通过这些数据构建客户流失预警模型，而且由于营销资源有限，希望结合客户特征进行有针对性的、高效率的开展客户挽留。
# 具体任务如下：
# 1.	读入aviation数据集，设置MEMBER_NO为索引列。（10分）
df = pd.read_excel('aviation.xls',index_col='MEMBER_NO')
print(df.info())
# 2.	剔除重复值、缺失值。（10分）
df.drop_duplicates(inplace=True)  # 去重
df.dropna(inplace=True)      # 删除缺失值
print(df.info())
# 3.	随机抽取500样本，切片特征X和标签Y。（10分）
data = df.sample(500)   # 抽样
datax = data.iloc[:,0:-1]
datay = data.iloc[:,-1]
# 4.	使用交叉验证方法（10折）比较逻辑回归、决策树算法性能差异，评估指标用F1分数（10分）
clf1 = DecisionTreeClassifier()    # 决策树
clf2 = LogisticRegression()        # 逻辑回归
model1 = cross_val_score(clf1,datax,datay,scoring='f1',cv=10)
model2 = cross_val_score(clf2,datax,datay,scoring='f1',cv=10)
print('决策树的F1分值为：')
print(model1)
print('均值：{}，标准差：{}'.format(model1.mean(),model1.std()))
print('逻辑回归的F1分值为：')
print(model2)
print('均值：{}，标准差：{}'.format(model2.mean(),model2.std()))
# 5.	使用网格搜索对上题中F1分数较高的算法进行超参数调优。（10分）
param = {'C':[0.1,1,10],           #np.aragr(0.1,1,0.3)等价于[0.1,0.4,0.7]
         'max_iter':[80,100,160]}
# 初始化出一个对象
searchmodel = GridSearchCV(estimator=clf2,
                           param_grid=param,
                           scoring='f1',
                           cv=10)
# 用网格搜索器进行训练
searchmodel.fit(datax,datay)
# 打印网格搜索后的最优分数
print(searchmodel.best_score_)
# 打印网格搜索后的最优参数组合
print(searchmodel.best_params_)
# 6.	使用4、5中确定的最优算法和最优参数建立模型。（10分）
model = LogisticRegression(C=1,max_iter=160)
# 7.	按照6：4划分数据集。（10分）
x = df.iloc[:,0:-1]
y = df.iloc[:,-1]
trainx,testx,trainy,testy = train_test_split(x,y,test_size=0.4,random_state=12345)
# 8.	使用训练集数据进行模型训练，对测试集数据进行预测，打印混淆矩阵。（10分）
model.fit(trainx,trainy)             # 对训练集进行训练
# 模型预测
prey = model.predict(testx)           # 预测的类标签----0或者1
print(metrics.confusion_matrix(testy,prey))
# 9.	打印精确率、召回率、F1分数和AUC值。（10分）
print('---------精确率---------------')
print(metrics.precision_score(testy,prey))
print('---------召回率---------------')
print(metrics.recall_score(testy,prey))
print('---------F1分值---------------')
print(metrics.f1_score(testy,prey))
print('---------AUC值---------------')
preproba = model.predict_proba(testx)
print(roc_auc_score(testy,preproba[:,1]))
# 10.	画出ROC曲线。（10分）
fpr,tpr,th = roc_curve(testy,preproba[:,1])
plt.xlabel('FPR')
plt.ylabel('TPR')
plt.title('ROC')
plt.plot(fpr,tpr)
plt.show()
